package com.ycy.smartcourseselection.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycy.smartcourseselection.common.*;
import com.ycy.smartcourseselection.dto.student.*;
import com.ycy.smartcourseselection.dto.teacher.FindAllTchDTO;
import com.ycy.smartcourseselection.entity.*;
import com.ycy.smartcourseselection.exception.CustomException;
import com.ycy.smartcourseselection.mapper.IStudentMapper;
import com.ycy.smartcourseselection.utils.CommonUtils;
import com.ycy.smartcourseselection.utils.PageUtils;
import com.ycy.smartcourseselection.utils.ValidateUtils;
import com.ycy.smartcourseselection.utils.WrapperUtils;
import com.ycy.smartcourseselection.vo.student.FileStuVO;
import com.ycy.smartcourseselection.vo.student.StudentVO;
import com.ycy.smartcourseselection.vo.teacher.FileTchVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;

import static cn.hutool.json.XMLTokener.entity;

@Service
public class StudentService extends ServiceImpl<IStudentMapper, Student> {
    PageUtils<Student, StudentVO> stuPageUtils = new PageUtils<>();

    //分页查学生信息
    public ResData<PageResVO<StudentVO>> findPageStu(FindPageStuDTO findPageStuDTO) {
        PageParamsDTO pageParamsDTO = findPageStuDTO.getPageParams();
        FindAllStuDTO otherParams = findPageStuDTO.getOtherParams();

        //验证pageNum，pageSize
        Integer pageNum = pageParamsDTO.getPageNum();
        Integer pageSize = pageParamsDTO.getPageSize();
        stuPageUtils.validatePageNumPageSize(pageNum, pageSize);

        QueryWrapper<Student> wrapper = WrapperUtils.buildAllStuWrapper(otherParams, new QueryWrapper<>());
        QueryWrapper<Student> newQueryWrapper = stuPageUtils.buildPageQueryWrapper(pageParamsDTO, wrapper);

        Page<Student> basePage = new Page<>(pageNum, pageSize);
        Page<Student> resPage = page(basePage, newQueryWrapper);

        ArrayList<StudentVO> VOList = new ArrayList<>();
        for (Student entity : resPage.getRecords()) {
            StudentVO VO = new StudentVO();
            BeanUtil.copyProperties(entity, VO);
            VOList.add(VO);
        }

        //构造分页结果
        PageResVO<StudentVO> pageResVO = stuPageUtils.getConditionResVO(resPage);
        pageResVO.setRows(VOList);

        return ResData.success(pageResVO);
    }
    //增加或修改学生信息
    public ResData<Boolean> saveStu(StudentDTO studentDTO) {
        String studentId = studentDTO.getStudentId();
        String stuName = studentDTO.getName();
        if(StrUtil.isBlank(studentId)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"学号不能为空");
        if(StrUtil.isBlank(stuName)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"姓名不能为空");

        QueryWrapper<Student> stuWrapper = new QueryWrapper<>();
        // stuWrapper.eq("is_delete",0);
        stuWrapper.eq("student_id",studentId);
        List<Student> stuList = list(stuWrapper);

        Student student = new Student();
        BeanUtil.copyProperties(studentDTO,student);

        boolean isAdd = StrUtil.isBlank(studentDTO.getId());
        if(isAdd) {
            if(stuList.size() != 0) throw new CustomException(ResCodeEnum.BAD_REQUEST,"该学号的学生信息已存在");
            String identityIdMessage = ValidateUtils.identityId(studentDTO.getIdentityId());
            System.out.println("identityIdMessage"+ identityIdMessage);
            if(!"".equals(identityIdMessage)) throw new CustomException(ResCodeEnum.BAD_REQUEST,identityIdMessage);
            String phoneMessage = ValidateUtils.phone(studentDTO.getPhone());
            System.out.println("phoneMessage"+ phoneMessage);
            if(!"".equals(phoneMessage)) throw new CustomException(ResCodeEnum.BAD_REQUEST,phoneMessage);
            String qqMessage = ValidateUtils.QQ(studentDTO.getQQ());
            System.out.println("qqMessage"+ qqMessage);
            if(!"".equals(qqMessage)) throw new CustomException(ResCodeEnum.BAD_REQUEST,qqMessage);
            student.setPassword(student.getIdentityId().substring(12));
        }

        if(isAdd) return ResData.success(saveOrUpdate(student),"添加成功");
        else return ResData.success(saveOrUpdate(student),"修改成功");
    }
    //批量删除学生信息
    public ResData<Boolean> falseDeleteStuByIds(List<String> idList) {
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", idList);
        List<Student> list = list(queryWrapper);
        // List<Student> list = studentService.list(queryWrapper);

        for (Student entity : list) {
            entity.setIsDelete(1);
        }

        return ResData.success(updateBatchById(list), "删除成功");
        // return ResData.success(studentService.updateBatchById(list), "删除成功");
    }
    //根据学号查询个人信息
    public ResData<StudentVO> getInfo(String studentId) {
        if(StrUtil.isBlank(studentId)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"学号不能为空");

        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id",studentId);
        List<Student> list = list(wrapper);

        if(list.size() == 0) throw new CustomException(ResCodeEnum.BAD_REQUEST,"该学号的学生不存在");
        if(list.size() > 1) throw new CustomException(ResCodeEnum.BAD_REQUEST,"错误地存在多个该学号的学生");

        StudentVO studentVO = new StudentVO();
        BeanUtil.copyProperties(list.get(0),studentVO);
        return ResData.success(studentVO);
    }
    //重设密码
    public ResData<Boolean> modifyPwd(ForgetStuPwdDTO forgetStuPwdDTO) {
        String id = forgetStuPwdDTO.getId();
        String password = forgetStuPwdDTO.getPassword();

        if(StrUtil.isBlank(id)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"学号不能为空");
        if(StrUtil.isBlank(password)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"新密码不能为空");

        Student student = new Student();
        BeanUtil.copyProperties(forgetStuPwdDTO,student);

        return ResData.success(saveOrUpdate(student));
    }
    //excel表导入学生信息
    public ResData<Boolean> stuInfoImport(MultipartFile file) {
        if (file == null) throw new CustomException(ResCodeEnum.BAD_REQUEST, "文件不能为空");

        ArrayList<Student> importList = new ArrayList<>();
        List<FileStuVO> fileVOList;
        try {
            InputStream inputStream = file.getInputStream();
            ExcelReader excelReader = ExcelUtil.getReader(inputStream);
            fileVOList = excelReader.readAll(FileStuVO.class);
            inputStream.close();
            excelReader.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(ResCodeEnum.SERVER_ERROR, "导入学生信息表格失败");
        }

        LinkedList<String> studentIdList = new LinkedList<>();
        for (FileStuVO fileVO : fileVOList) studentIdList.addFirst(fileVO.getStudentId());

        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.in("student_id", studentIdList);
        wrapper.select("student_id");
        List<Student> entityList = list(wrapper);
        if (entityList.size() != 0) {
            LinkedList<String> sameStudentIdList = new LinkedList<>();
            for (Student entity : entityList) sameStudentIdList.addFirst(entity.getStudentId());
            throw new CustomException(ResCodeEnum.BAD_REQUEST, "系统中已存在如下学号的学生：", sameStudentIdList.toString());
        }

        for (FileStuVO fileVO : fileVOList) {
            String studentId = fileVO.getStudentId();
            String name = fileVO.getName();
            String phone = fileVO.getPhone();
            String sex = fileVO.getSex();
            String qq = fileVO.getQQ();
            String identityId = fileVO.getIdentityId();
            String grade = fileVO.getGrade();
            String college = fileVO.getCollege();
            String major = fileVO.getMajor();
            String stuClass = fileVO.getStuClass();

            if (StrUtil.isBlank(studentId)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生的学号为空,请检查");
            if (StrUtil.isBlank(name)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有教师的姓名为空,请检查");
            if (StrUtil.isBlank(phone)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生联系电话为空,请检查");
            if (StrUtil.isBlank(sex)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生性别为空,请检查");
            if (StrUtil.isBlank(qq)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生QQ为空,请检查");
            if (StrUtil.isBlank(identityId)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生身份证号为空,请检查");
            if (StrUtil.isBlank(college)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生学院为空,请检查");
            if (StrUtil.isBlank(major)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生专业为空,请检查");
            if (StrUtil.isBlank(stuClass)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生班级为空,请检查");
            if (StrUtil.isBlank(grade)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生年级为空,请检查");

            String errMessage = CommonUtils.validateIdentityIdPhoneQQ(identityId, phone, qq);
            if (!"".equals(errMessage)) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有学生的" + errMessage);

            Student student = new Student();
            student.setPassword(identityId.substring(12));
            if ("男".equals(sex)) student.setSex(1);
            else student.setSex(0);

            BeanUtils.copyProperties(fileVO, student, "sex");

            importList.add(student);
        }

        return ResData.success(saveBatch(importList));
    }
    //表格导出(导出不需要返回参数)
    public void stuInfoExport(HttpServletResponse response, FindAllStuDTO findAllStuDTO) {
        QueryWrapper<Student> wrapper = WrapperUtils.buildAllStuWrapper(findAllStuDTO, new QueryWrapper<>());
        List<Student> entityList = list(wrapper);

        //1. 所有学生列表，每一项处理后拷贝到 ExportVO的列表中
        ArrayList<FileStuVO> exportVOList = new ArrayList<>();
        for (int i = 0; i < entityList.size(); i++) {
            Student entity = entityList.get(i);
            FileStuVO exportVO = new FileStuVO();
            exportVO.setOrder(i + 1);
            BeanUtils.copyProperties(entity, exportVO, "sex");

            if (entity.getSex() == 1) exportVO.setSex("男");
            else exportVO.setSex("女");

            exportVOList.add(exportVO);
        }
        //2. 在UserExportVO类中给每个属性用 @Alias(value = "中文名")的注解添加中文名

        try {
            //3. 用ExcelUtil获取 excelWriter对象
            ExcelWriter excelWriter = ExcelUtil.getWriter(true);

            //4.将UserExportVO的列表写入excelWriter中，并添加中文名表头
            excelWriter.write(exportVOList, true);

            //5.设置浏览器响应的格式
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            String fileName = URLEncoder.encode("学生信息", "UTF-8");  //设置文件名称,并进行编码
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");  //将文件名设置到 response的 header中

            //6.用response来货如输出流
            ServletOutputStream outputStream = response.getOutputStream();

            //7. 将输出流刷新到 excelWriter对象中，并关闭输出流和excelWriter对象
            excelWriter.flush(outputStream, true);
            outputStream.close();
            excelWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(ResCodeEnum.SERVER_ERROR,"导出学生信息表格失败");
        }
    }
}
